package com.wmapp.web;

import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.wmapp.connect.ConnectConfig;
import com.wmapp.connect.Connection;
import com.wmapp.connect.Request;
import com.wmapp.connect.SocketSupport;
import com.wmapp.domain.Administrator;
import com.wmapp.domain.LoginInfo;
import com.wmapp.domain.MCU;
import com.wmapp.domain.MCUVersion;
import com.wmapp.language.Lang;
import com.wmapp.language.LangImpl;
import com.wmapp.service.ManagerService;
import com.wmapp.service.SetupService;
import com.wmapp.service.ViewService;
import com.wmapp.utils.DomainUtils;
import com.wmapp.utils.SimpleStringUtils;

@Controller
@RequestMapping("/perm")
public class PermissionController {
	private static Log log=LogFactory.getLog(PermissionController.class);
	
	private ManagerService managerService;
	private SetupService setupService;
	private ViewService viewService;
	
	private Lang lang;
	
	@Autowired
	public void setLang(Lang lang) {
		this.lang = lang;
	}
	
	@Autowired
	public void setManagerService(ManagerService managerService) {
		this.managerService = managerService;
	}
	
	@Autowired
	public void setSetupService(SetupService setupService) {
		this.setupService = setupService;
	}

	@Autowired
	public void setViewService(ViewService viewService) {
		this.viewService = viewService;
	}
	
	@RequestMapping(value="/touch",method=RequestMethod.GET)
	public void touch(HttpServletRequest request,HttpServletResponse response){
		// nothing ,just for trigger authorization filter
	}
	
	@RequestMapping(value="/login",method=RequestMethod.POST)
	public String login(@RequestParam(value="username",required=true) String username,
			@RequestParam(value="pwd",required=true) String pwd,HttpSession session){
		try {
			String locale=(String)session.getAttribute("locale");
			
			if(!StringUtils.hasText(locale))
				locale=LangImpl.EN;
				
			lang.setLocale(locale);	
			
			Administrator admin=managerService.getAdminByName(username);
			if(admin==null){
				return SimpleStringUtils.join("redirect:/index.jsp?errorcode=1&lang=",locale);
			}else if(!pwd.equals(admin.getPassword())){
				return SimpleStringUtils.join("redirect:/index.jsp?errorcode=2&lang=",locale);
			}else{

				LoginInfo loginInfo=new LoginInfo();
				loginInfo.setUsername(username);
				loginInfo.setLocalUsername(username);
				loginInfo.setMcuIP(ConnectConfig.DEFAULT_IP);
				loginInfo.setMcuName("local");
				loginInfo.setAccesslevel(admin.getAccesslevel());
				loginInfo.setLocalAccesslevel(admin.getAccesslevel());
				loginInfo.setGrouplimit(admin.getGrouplimit());
				loginInfo.setLocalGrouplimit(admin.getGrouplimit());
				loginInfo.setGroup(admin.getGroup());
				loginInfo.setLocalGroup(admin.getGroup());
				
				MCUVersion mcuVersion = viewService.getMCUVersion();
				loginInfo.setH264definition(mcuVersion.getH264definition());
                                loginInfo.setMaxPortNum(mcuVersion.getCapbility());
				session.setAttribute("loginInfo", loginInfo);
			}
		} catch (Exception e) {
			log.warn(e.getMessage(),e);
			return "redirect:/index.jsp?errorcode=3";
		}
		
		return "redirect:/app/manage/main";
	}
	
	@RequestMapping(value="/logout",method=RequestMethod.GET)
	public String logout(HttpSession session){
		session.removeAttribute("loginInfo");
		lang.setLocale(LangImpl.EN);
		setServiceConnect(ConnectConfig.DEFAULT_IP, 5040);
		return "redirect:/index.jsp";
	}
	
	@RequestMapping(value="/connect/local",method=RequestMethod.GET)
	@ResponseBody
	public String connect(HttpSession session){
		JSONObject ret=new JSONObject();
		try {
			setServiceConnect(ConnectConfig.DEFAULT_IP, 5040);
			LoginInfo loginInfo=(LoginInfo)session.getAttribute("loginInfo");
			loginInfo.setUsername(loginInfo.getLocalUsername());
			loginInfo.setMcuIP(ConnectConfig.DEFAULT_IP);
			loginInfo.setMcuName("local");
			loginInfo.setAccesslevel(loginInfo.getLocalAccesslevel());
			loginInfo.setGrouplimit(loginInfo.getLocalGrouplimit());
			loginInfo.setGroup(loginInfo.getLocalGroup());
			
			MCUVersion mcuVersion = viewService.getMCUVersion();
			loginInfo.setH264definition(mcuVersion.getH264definition());
			
			ret.put("success", "true");
			return ret.toString();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			ret.put("success", "false");
			ret.put("msg", lang.getMsg("common.tip.connect.fail"));
			return ret.toString();
		}
	}
	
	@RequestMapping(value="/connect",method=RequestMethod.POST)
	@ResponseBody
	public String connect(@RequestParam(value="mcuid",required=true) String mcuid,HttpSession session){
		JSONObject ret=new JSONObject();
		String success="false";
		
		Connection conn=null;
		try {
			MCU mcu=managerService.getMCUById(mcuid);
			String address=mcu.getAddress();
			int port=Integer.valueOf(mcu.getPort());
			String username=mcu.getUser();
			
			conn=new Connection(address, port);
			Request req=new Request(Request.GET_ADMIN_LIST_REQ);
			conn.sendXML(req.getContent());
			
			String receiveXML=conn.receiveXML();
			List<Administrator> list = DomainUtils.xml2List(receiveXML,"/administrators/administrator",Administrator.class);
			
			for (Iterator iterator = list.iterator(); iterator.hasNext();) {
				Administrator administrator = (Administrator) iterator.next();
				
				if(username.equals(administrator.getName())
						&&mcu.getPassword().equals(administrator.getPassword())){
					success="true";
					
					setServiceConnect(address, port);
					
					LoginInfo loginInfo=(LoginInfo)session.getAttribute("loginInfo");
					loginInfo.setUsername(username);
					loginInfo.setMcuIP(address);
					loginInfo.setMcuName(mcu.getName());
					loginInfo.setAccesslevel(administrator.getAccesslevel());
					loginInfo.setGrouplimit(administrator.getGrouplimit());
					loginInfo.setGroup(administrator.getGroup());
					
					loginInfo.setManagerprotocol(mcu.getManagerprotocol());
					loginInfo.setManagerport(mcu.getManagerport());
					loginInfo.setManagername(mcu.getManagername());
					
					MCUVersion mcuVersion = viewService.getMCUVersion();
					loginInfo.setH264definition(mcuVersion.getH264definition());
					
					break;
				}
				
			}
			
			ret.put("success", success);
			if(success.equals("false")){
				ret.put("msg", lang.getMsg("common.tip.connect.fail"));
			}
			return ret.toString();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			ret.put("success", "false");
			ret.put("msg", lang.getMsg("common.tip.connect.fail"));
			return ret.toString();
		} finally{
			if(conn!=null){
				conn.close();
			}
		}
	}
	
	private void setServiceConnect(String ip,int port){
		SocketSupport managerSocketSupport = (SocketSupport)managerService;
		SocketSupport setupSocketSupport = (SocketSupport)setupService;
		SocketSupport viewSocketSupport = (SocketSupport)viewService;
		
		managerSocketSupport.setConnectConfig(new ConnectConfig(ip,port));
		setupSocketSupport.setConnectConfig(new ConnectConfig(ip,port));
		viewSocketSupport.setConnectConfig(new ConnectConfig(ip,port));
	}
}
